package net.csdra.place.component;

import net.csdra.basis.Utils;
import net.csdra.basis.service.CurrentUserInfo;
import net.csdra.basis.service.ServiceBaseInterfaceImpl;
import net.csdra.place.domain.ReservationPlace;
import net.csdra.place.domain.ReservationPlaceRepository;
import net.csdra.place.domain.ReservationState;
import net.csdra.place.component.form.CreateReservationPlace;
import net.csdra.place.component.form.UpdateReservationPlace;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.util.Assert;

import java.sql.Timestamp;
import java.util.List;

/**
 * Created by msf on 2018/1/29.
 */
public class ReservationPlaceComponentImpl extends ServiceBaseInterfaceImpl<ReservationPlace, CreateReservationPlace, UpdateReservationPlace> implements ReservationPlaceComponent {

    ReservationPlaceRepository reservationPlaceRepository;
    CurrentUserInfo currentUserInfo;

    public ReservationPlaceComponentImpl(ReservationPlaceRepository reservationPlaceRepository, CurrentUserInfo currentUserInfo) {
        super(ReservationPlace.class, reservationPlaceRepository, currentUserInfo);
        this.reservationPlaceRepository = reservationPlaceRepository;
        this.currentUserInfo = currentUserInfo;
    }

    /**
     * 创建预约
     *
     * @param createReservationPlace
     * @return
     */
    @Override
    public ReservationPlace create(CreateReservationPlace createReservationPlace) {
        //TODO 补充必要断言
        /// RETODO
        Assert.notNull(createReservationPlace, "传入参数为空");
        Assert.hasText(createReservationPlace.getMetaId(), "metaId为空");
        Assert.notNull(createReservationPlace.getCustomize(), "customize为空");
        int i = countByMetaIdAndBeginAndEndAndStatePrivate(createReservationPlace.getMetaId(), createReservationPlace.getBegin(), createReservationPlace.getEnd(), ReservationState.RESERVATION_ALLOW);
        Assert.state(i == 0, "@时间段有冲突");
        ReservationPlace reservationPlace = Utils.createAutoSet(ReservationPlace.class, currentUserInfo.get().getUserName());
        //TODO 补充剩余属性
        /// RETODO
        BeanUtils.copyProperties(createReservationPlace, reservationPlace);
        reservationPlace.setReservationState(ReservationState.RESERVATION_ING);
        reservationPlaceRepository.save(reservationPlace);
        ReservationPlace result = new ReservationPlace();
        Utils.copyProperties(reservationPlace, result);
        return result;
    }

    /**
     * 审批预约
     *
     * @param updateReservationPlace
     * @return
     */
    @Override
    public ReservationPlace update(UpdateReservationPlace updateReservationPlace) {
        //TODO 补充必要断言
        /// RETODO
        Assert.notNull(updateReservationPlace, "传入参数为空");
        Assert.hasText(updateReservationPlace.getId(), "id为空");
        Assert.notNull(updateReservationPlace.getCustomize(), "customize为空");
        ReservationPlace reservationPlace = reservationPlaceRepository.findOne(updateReservationPlace.getId());
        Assert.notNull(reservationPlace, "@找不到此预约记录");
        Assert.state(updateReservationPlace.getReservationState().equals(ReservationState.RESERVATION_ALLOW) || updateReservationPlace.getReservationState().equals(ReservationState.RESERVATION_REJECT), "@状态错误");
        Utils.updateAutoSet(reservationPlace, currentUserInfo.get().getUserName());
        reservationPlace.setReservationState(updateReservationPlace.getReservationState());
        reservationPlaceRepository.save(reservationPlace);
        ReservationPlace result = new ReservationPlace();
        Utils.copyProperties(reservationPlace, result);
        return result;
    }


    @Override
    public List<ReservationPlace> findAllByMetaIdAndBeGinAndEnd(String metaId, Timestamp begin, Timestamp end, String reservationState) {
        //TODO 根据metaId、begin、end和resrvationState查询所有ReservationPlace
        /// RETODO
        List<ReservationPlace> reservationPlaceList = reservationPlaceRepository.findAllByMetaIdAndStateAndBeginAndEnd(metaId, reservationState, begin, end);
        return reservationPlaceList;
    }

    @Override
    public int countByMetaIdAndBeginAndEndAndState(String metaId, Timestamp begin, Timestamp end, String reservationState) {
        return countByMetaIdAndBeginAndEndAndStatePrivate(metaId, begin, end, reservationState);
    }

    @Override
    public Page<ReservationPlace> findPageByMetaIdAndBeginAndEnd(String metaId, Timestamp begin, Timestamp end, String reservationState, Pageable pageable) {
        //TODO 根据metaId、begin、end和resrvationState查询所有ReservationPlace并分页
        /// RETODO
        Page<ReservationPlace> reservationPlacesPage = reservationPlaceRepository.findPageByMetaIdAndStateAndBeginAndEnd(metaId, reservationState, begin, end, pageable);
        return reservationPlacesPage;
    }

    @Override
    public List<ReservationPlace> findAllByDistrictIdAndBeGinAndEnd(String districtId, Timestamp begin, Timestamp end, String reservationState) {
        //TODO
        /// RETODO
        List<ReservationPlace> reservationPlaceList = reservationPlaceRepository.findByMetaIdAndReservationStateAndCreateTimeBetween(districtId, reservationState, begin, end);
        return reservationPlaceList;
    }

    @Override
    public int countByDistrictIdAndBeginAndEndAndState(String districtId, Timestamp begin, Timestamp end, String reservationState) {
        //TODO
        /// RETODO
        List<ReservationPlace> reservationPlaceList = reservationPlaceRepository.findByMetaIdAndReservationStateAndCreateTimeBetween(districtId, reservationState, begin, end);
        return reservationPlaceList.size();
    }

    @Override
    public int countAllByDistrictIdAndBeginAndEndAndState(String districtId, Timestamp begin, Timestamp end, String reservationState) {
        // TODO 计算总和
        // RETODO 位置不对，此处需要查询镇街节点，不属于单表查询,已移到 service/place/ReservationPlaceServiceImpl
        return 0;
    }

    @Override
    public Page<ReservationPlace> findPageByDistrictIdAndBeginAndEnd(String districtId, Timestamp begin, Timestamp end, String reservationState, Pageable pageable) {
        //TODO
        /// RETODO
        Page<ReservationPlace> reservationPlacePage = reservationPlaceRepository.findByMetaIdAndReservationStateAndCreateTimeBetween(districtId, reservationState, begin, end, pageable);
        return reservationPlacePage;
    }

    /**
     * 根据MetaId、begin和end判断是否有冲突
     *
     * @param metaId
     * @param begin
     * @param end
     * @return true：无冲突，false：有冲突
     */
    private int countByMetaIdAndBeginAndEndAndStatePrivate(String metaId, Timestamp begin, Timestamp end, String reservationState) {
        //TODO 根据metaId、begin、end和resrvationState计算过出所有ReservationPlace
        /// RETODO
        List<ReservationPlace> reservationPlaceList = reservationPlaceRepository.findAllByMetaIdAndStateAndBeginAndEnd(metaId, reservationState, begin, end);
        return reservationPlaceList.size();
    }


    @Override
    public ReservationPlace enabledCurrent(String id, boolean isEnabled) {
        throw new RuntimeException("#此实体不需实现此方法");
    }

    @Override
    public void deleteCurrent(String id) {
        throw new RuntimeException("#此实体不需实现此方法");
    }
}
